Dis-assembling Programs

This chapter describes the purpose and usage of the disassembler, available by using the `-d' option from the command-line. The dis-assembler has several uses: However, the dis-assembler will not normally help users debug their programs. It is a tool for working on the executable, rather than a tool for working with the language. The dis-assembler produces a readable representation of the virtual-machine codes. It is recommended that the the `-q', `-l', and `-n' be used in conjunction with the `-d' option, since this combination will produce more readable output. It is almost essential, unless you are extremely patient, to use the `-l' option, which will prevent loading of all the R-files in the rlib directory. Failure to use `-l' in conjunction with `-d' will force you to wait an extremely long time while the op-codes for each library function are printed to the screen. The `-n' option merely suppresses the generation of file and line number information, and makes the output more readable. For example, lets invoke with the correct options and look at the output from a simple expression:
augerinn:~$ rlab -qrldn
Welcome to RLaB. New users type `help INTRO'
RLaB version 0.97d beta Copyright (C) 1992, 93, 94 Ian Searle
RLaB comes with ABSOLUTELY NO WARRANTY; for details type `help WARRANTY'
This is free software, and you are welcome to redistribute it under
certain conditions; type `help CONDITIONS' for details
> 1 + 3 - 2  
   1: push constant
   2: 1
   3: push constant
   4: 3
   5: add
   6: push constant
   7: 2
   8: sub
   9: print
  10: stop
        2
What you see is the internal representation of the expression `1 + 3 - 2'. The parser generates the op-codes and stores them internally for execution by the virtual-machine. The virtual-machine in is a internal stack-machine which sequentially executes integer instructions. The instructions, or op-codes, are created as each statement is read and parsed. The op-codes are then executed as soon as a valid end-of-statement is reached. For user-functions, the op-codes are stored as variables, then executed each time the variable is used in a function evaluation. Therefore, a function need only be parsed the first time it is used. Now let us look at the use of a variable assignment. The only real difference between this and the previous example is the use of the assign operator.
> a = 3
   1: push var
   2: a
   3: push constant
   4: 3
   5: assign
   6: print
   7: stop
 a =
        3
The use of a trailing semi-colon makes a slight change - the print is changed to a pop clean.
> a = 3;
   1: push var
   2: a
   3: push constant
   4: 3
   5: assign
   6: pop clean
   7: stop
Combining the operation and assign operators is just as you would expect, with the result being calculated, then assigned to the left hand side variable.
> b = a - 2
   1: push var
   2: b
   3: push var
   4: a
   5: push constant
   6: 2
   7: sub
   8: assign
   9: print
  10: stop
 b =
        1
The stack supports two basic operations, push and pop, as well as some other operations that are unique to . To fully understand the op-codes it is necessary to look at the source code; an understanding of ``YACC-like'' BNF grammars, and C is also required. If you understand stack-machines many of the operations can be deduced. However, some of the operations are confusing when expressed in op-codes. For example a function call with expressions embedded in the argument list:
> sqrt ( (1+2)*3 )
   1: push var
   2: sqrt
   3: push constant
   4: 1
   5: push constant
   6: 2
   7: add
   8: push constant
   9: 3
  10: multiply
  11: function call
  12: 1
  13: print
  14: stop
        3
This example is somewhat confusing because sqrt seems to be treated like an ordinary variable; it is, and it should be. The `function call'' op-code does not appear until the 11th op-code, well after the variable sqrt has been pushed on the stack. You probably wouldn't figure out that the number 1, the 12th op-code, is the number of function arguments unless you had looked at the grammar for function evaluations. In conclusion, the `-d' command-line option is primarily available since is a distributed as source code, It does not make much sense to ``hide'' features in programs distributed this way. The dis-assembler may never be fully documented, certainly not until after version 1.0 of has been released. Most users should never need to use this option.